/*
 * Galaxium Messenger
 *
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * Copyright (C) 2007 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

namespace Galaxium.Core
{
	// Like System.Collections.Generic.Dictionary, but it retains the order in which items are added
	public class OrderedDictionary<K,V>: List<KeyValuePair<K,V>>
	{
		bool _allowDupKeys = false;
		
		public OrderedDictionary (bool allowDuplicateKeys)
		{
			_allowDupKeys = allowDuplicateKeys;
		}
		
		public OrderedDictionary (): this(false) { }
		
		public IEnumerable<K> Keys
		{
			get
			{
				foreach (KeyValuePair<K,V> pair in this)
					yield return pair.Key;
			}
		}
		
		public IEnumerable<V> Values
		{
			get
			{
				foreach (KeyValuePair<K,V> pair in this)
					yield return pair.Value;
			}
		}
		
		public void Add (K key, V val)
		{
			if (!_allowDupKeys && ContainsKey (key))
				throw new Exception ("Duplicate Key");
		
			base.Add (new KeyValuePair<K, V> (key, val));
		}
		
		public bool ContainsKey (K key)
		{
			foreach (K existing in Keys)
			{
				if (existing.Equals (key))
					return true;
			}
			
			return false;
		}
		
		public bool ContainsValue (V val)
		{
			foreach (V existing in Values)
			{
				if (existing.Equals (val))
					return true;
			}
			
			return false;
		}
		
		public void Insert (int index, K key, V val)
		{
			if (!_allowDupKeys && ContainsKey (key))
				throw new Exception ("Duplicate Key");
		
			base.Insert (index, new KeyValuePair<K, V> (key, val));
		}
		
		public void Remove (K key)
		{
			for (int i = 0; i < Count; i++)
			{
				if (base[i].Key.Equals (key))
				{
					base.RemoveAt (i);
					return;
				}
			}
			
			throw new Exception ("Key not found");
		}
		
		public V this[K key]
		{
			get
			{
				for (int i = 0; i < Count; i++)
				{
					if (base[i].Key.Equals (key))
						return base[i].Value;
				}
				
				return default (V);
			}
			set
			{
				for (int i = 0; i < Count; i++)
				{
					if (base[i].Key.Equals (key))
					{
						base[i] = new KeyValuePair<K,V> (key, value);
						return;
					}
				}
				
				Add (key, value);
			}
		}
	}
}
